from tests.pytests.helpers.codegen_helpers import compile_chunk, assert_code_contains


def test_basic_fstring():
    """测试基本的f-string功能"""

    def format_basic(name: str, age: int) -> str:
        return f"Hello {name}, you are {age} years old"

    block = compile_chunk(format_basic)
    assert_code_contains(
        block,
        """
        std::string format_basic(const std::string& name, int age) {
            return sformat("Hello {}, you are {} years old", (name), (age));
        }
        """,
    )


def test_fstring_with_brace_escaping():
    """测试f-string中的大括号转义"""

    def format_with_braces(name: str) -> str:
        return f"{{Hello {name}!}}"

    block = compile_chunk(format_with_braces)
    assert_code_contains(
        block,
        """
        std::string format_with_braces(const std::string& name) {
            return sformat("{{Hello {}!}}", (name));
        }
        """,
    )


def test_fstring_multiple_escaping():
    """测试多重大括号转义"""

    def format_nested() -> str:
        return f"{{{{nested}}}}"

    block = compile_chunk(format_nested)
    assert_code_contains(
        block,
        """
        std::string format_nested() {
            return sformat("{{{{nested}}}}");
        }
        """,
    )


def test_fstring_mixed_escaping():
    """测试混合转义和变量"""

    def format_mixed(key: str, value: int) -> str:
        return f"{{key: {key}, value: {value}}}"

    block = compile_chunk(format_mixed)
    assert_code_contains(
        block,
        """
        std::string format_mixed(const std::string& key, int value) {
            return sformat("{{key: {}, value: {}}}", (key), (value));
        }
        """,
    )


def test_fstring_complex_nesting():
    """测试复杂嵌套转义"""

    def format_complex(name: str) -> str:
        return f"{{outer {{inner {name}}} outer}}"

    block = compile_chunk(format_complex)
    assert_code_contains(
        block,
        """
        std::string format_complex(const std::string& name) {
            return sformat("{{outer {{inner {}}} outer}}", (name));
        }
        """,
    )


def test_fstring_only_escaping():
    """测试纯转义无变量"""

    def format_static() -> str:
        return f"{{static}}"

    block = compile_chunk(format_static)
    assert_code_contains(
        block,
        """
        std::string format_static() {
            return sformat("{{static}}");
        }
        """,
    )


def test_fstring_empty_braces():
    """测试空大括号转义"""

    def format_empty(name: str) -> str:
        return f"{{}}{name}{{}}"

    block = compile_chunk(format_empty)
    assert_code_contains(
        block,
        """
        std::string format_empty(const std::string& name) {
            return sformat("{{}}{}{{}}", (name));
        }
        """,
    )


def test_fstring_with_format_spec():
    """测试带格式规范符的f-string"""

    def format_with_spec(value: float, width: int) -> str:
        return f"Value: {value:.2f}, Width: {width:>5}"

    block = compile_chunk(format_with_spec)
    assert_code_contains(
        block,
        """
        std::string format_with_spec(double value, int width) {
            return sformat("Value: {:.2f}, Width: {:>5}", (value), (width));
        }
        """,
    )


def test_fstring_multiple_variables():
    """测试多个变量的f-string"""

    def format_multiple(a: int, b: str, c: float) -> str:
        return f"a={a}, b={b}, c={c}"

    block = compile_chunk(format_multiple)
    assert_code_contains(
        block,
        """
        std::string format_multiple(int a, const std::string& b, double c) {
            return sformat("a={}, b={}, c={}", (a), (b), (c));
        }
        """,
    )


def test_fstring_with_expressions():
    """测试包含表达式的f-string"""

    def format_expr(x: int, y: int) -> str:
        return f"Sum: {x + y}, Product: {x * y}"

    block = compile_chunk(format_expr)
    assert_code_contains(
        block,
        """
        std::string format_expr(int x, int y) {
            return sformat("Sum: {}, Product: {}", (x + y), (x * y));
        }
        """,
    )


def test_fstring_edge_cases():
    """测试f-string边界情况"""

    def format_edge_cases(name: str) -> str:
        # 连续多个转义大括号
        case1 = f"{{{{{{multiple}}}}}}"
        # 转义大括号与变量混合
        case2 = f"{{start}} {name} {{end}}"
        return case1 + case2

    block = compile_chunk(format_edge_cases)
    assert_code_contains(
        block,
        """
        std::string format_edge_cases(const std::string& name) {
            std::string case1 = sformat("{{{{{{multiple}}}}}}");
            std::string case2 = sformat("{{start}} {} {{end}}", (name));
            return case1 + case2;
        }
        """,
    )


def test_fstring_in_return_statement():
    """测试在return语句中的f-string"""

    def get_message(user: str, count: int) -> str:
        return f"User {user} has {count} items"

    block = compile_chunk(get_message)
    assert_code_contains(
        block,
        """
        std::string get_message(const std::string& user, int count) {
            return sformat("User {} has {} items", (user), (count));
        }
        """,
    )


def test_fstring_in_assignment():
    """测试在赋值语句中的f-string"""

    def create_message(name: str, age: int) -> str:
        message = f"Name: {name}, Age: {age}"
        return message

    block = compile_chunk(create_message)
    assert_code_contains(
        block,
        """
        std::string create_message(const std::string& name, int age) {
            std::string message = sformat("Name: {}, Age: {}", (name), (age));
            return message;
        }
        """,
    )
